﻿#ifndef WRWORKTCPCOMMCLIENTDATASOURCE
#define WRWORKTCPCOMMCLIENTDATASOURCE

#include "WRWorkTcpCommClientInterface.h"
#include "WRWorkTcpCommClientInterfaceActivator.h"
#include "../WRWorkTcpComm.h"
#include "../WRWorkTcpCommConsts.h"
#include "../../WRSoft-Utility/Framing/WRDataHandlers.h"
#include "../../WRSoft-Utility/Runtime/WRDataPacket.h"
#include "../../WRSoft-Utility/Structs/WRBuffer.h"

/********************
class ArgsParser
{
public:
    bool parse(const unsigned char* buf, int len, T& val);
};
class DataParser
{
public:
    bool parse(const unsigned char* buf, int len, T& val);
};
********************/

//表示工作TCP通讯客户端数据源接口。
template <class TArgs, class TData, class TArgsParser, class TDataParser>
class WRWorkTcpCommClientDataSource : public WRWorkTcpCommClientInterface, public WRDataHandlers<TArgs, TData>
{
private:
    int m_bufSize;//缓存数量
    int m_pkgSize;//每包大小
    TArgsParser m_argsParser;
    TDataParser m_dataParser;
    WRBuffer<unsigned char>* m_dataBuffer;//数据缓存
    int m_dataLength;

protected:
    //当指定的观察者添加前调用此方法。
    void onAdding(WRObservers<WRDataHandler>::Observer observer)
    {
        WRDataHandlers<TArgs, TData>::onAdding(observer);
        if (WRObservers<WRDataHandler>::m_count == 0)
        {
            WRWorkTcpCommClientSession* session = object()->session();
            if (session->effective())
            {
                WRDataPacket* packet;
                if (affair())
                {
                    char* p;
                    packet = WRDataPacket::allocate<40>();
                    packet->buffer(&p);

                    WRBytes::write((WR32u)WRWorkTcpComm::FrameHeader, p);//帧头
                    WRBytes::write((WR32s)(40), p + 4);//帧长度
                    WRBytes::write((WR16u)(object()->index()), p + 8);//工作对象索引
                    WRBytes::write((WR16u)WRWorkTcpComm::WorkObjectAffair, p + 10);//类型（工作事务）
                    WRBytes::write((WR32s)(affair()->id()), p + 12);
                    WRBytes::write((WR16u)(affair()->index()), p + 16);//工作事务索引
                    WRBytes::write((WR16u)WRWorkTcpComm::WorkAffairIITreat, p + 18);//类型（处理）
                    WRBytes::write((WR16u)(index()), p + 20);//索引
                    WRBytes::write((WR16u)WRWorkTcpComm::DataStarted, p + 22);//动作
                    WRBytes::write((WR32s)(m_bufSize), p + 24);//缓存个数
                    WRBytes::write((WR32s)(m_pkgSize), p + 28);//分包大小
                    WRBytes::write((WR32u)WRWorkTcpComm::FrameVersion, p + 32);//版本
                    WRBytes::write((WR32u)WRWorkTcpComm::FrameTailor, p + 36);//帧尾
                }
                else
                {
                    char* p;
                    packet = WRDataPacket::allocate<32>();
                    packet->buffer(&p);

                    WRBytes::write((WR32u)WRWorkTcpComm::FrameHeader, p);//帧头
                    WRBytes::write((WR32s)(32), p + 4);//帧长度
                    WRBytes::write((WR16u)(object()->index()), p + 8);//工作对象索引
                    WRBytes::write((WR16u)WRWorkTcpComm::WorkObjectIITreat, p + 10);//类型（处理）
                    WRBytes::write((WR16u)(index()), p + 12);//索引
                    WRBytes::write((WR16u)WRWorkTcpComm::DataStarted, p + 14);//动作
                    WRBytes::write((WR32s)(m_bufSize), p + 16);//缓存个数
                    WRBytes::write((WR32s)(m_pkgSize), p + 20);//分包大小
                    WRBytes::write((WR32u)WRWorkTcpComm::FrameVersion, p + 24);//版本
                    WRBytes::write((WR32u)WRWorkTcpComm::FrameTailor, p + 28);//帧尾
                }
                if (!session->sendData(packet))
                {
                    packet->release();
                }
            }
        }
    }
    //当指定的观察者移除后调用此方法。
    void onRemoved(WRObservers<WRDataHandler>::Observer observer)
    {
        if (WRObservers<WRDataHandler>::m_count == 0)
        {
            WRWorkTcpCommClientSession* session = object()->session();
            if (session->effective())
            {
                WRDataPacket* packet;
                if (affair())
                {
                    char* p;
                    packet = WRDataPacket::allocate<32>();
                    packet->buffer(&p);

                    WRBytes::write((WR32u)WRWorkTcpComm::FrameHeader, p);//帧头
                    WRBytes::write((WR32s)(32), p + 4);//帧长度
                    WRBytes::write((WR16u)(object()->index()), p + 8);//工作对象索引
                    WRBytes::write((WR16u)WRWorkTcpComm::WorkObjectAffair, p + 10);//类型（工作事务）
                    WRBytes::write((WR32s)(affair()->id()), p + 12);
                    WRBytes::write((WR16u)(affair()->index()), p + 16);//工作事务索引
                    WRBytes::write((WR16u)WRWorkTcpComm::WorkAffairIITreat, p + 18);//类型（处理）
                    WRBytes::write((WR16u)(index()), p + 20);//索引
                    WRBytes::write((WR16u)WRWorkTcpComm::DataStopped, p + 22);//动作
                    WRBytes::write((WR32u)WRWorkTcpComm::FrameVersion, p + 24);//版本
                    WRBytes::write((WR32u)WRWorkTcpComm::FrameTailor, p + 28);//帧尾
                }
                else
                {
                    char* p;
                    packet = WRDataPacket::allocate<24>();
                    packet->buffer(&p);

                    WRBytes::write((WR32u)WRWorkTcpComm::FrameHeader, p);//帧头
                    WRBytes::write((WR32s)(24), p + 4);//帧长度
                    WRBytes::write((WR16u)(object()->index()), p + 8);//工作对象索引
                    WRBytes::write((WR16u)WRWorkTcpComm::WorkObjectIITreat, p + 10);//类型（处理）
                    WRBytes::write((WR16u)(index()), p + 12);//索引
                    WRBytes::write((WR16u)WRWorkTcpComm::DataStopped, p + 14);//动作
                    WRBytes::write((WR32u)WRWorkTcpComm::FrameVersion, p + 16);//版本
                    WRBytes::write((WR32u)WRWorkTcpComm::FrameTailor, p + 20);//帧尾
                }
                if (!session->sendData(packet))
                {
                    packet->release();
                }
            }
        }
        WRDataHandlers<TArgs, TData>::onRemoved(observer);
    }

public:
    //初始化工作TCP通讯客户端 数据源接口。
    WRWorkTcpCommClientDataSource(const QUuid& uuid, const QString& name, int index, WRWorkTcpCommClientObject* target, int buffers = WRWorkTcpComm::DefaultDataBuffers, int packets = WRWorkTcpComm::DefaultDataPackets)
        : WRWorkTcpCommClientInterface(uuid, name, index, target), m_bufSize(buffers), m_pkgSize(packets), m_dataBuffer(0)
    {
        //add code here
    }
    //初始化工作TCP通讯客户端 数据源接口。
    WRWorkTcpCommClientDataSource(const QUuid& uuid, const QString& name, int index, WRWorkTcpCommClientAffair* target, int buffers = WRWorkTcpComm::DefaultDataBuffers, int packets = WRWorkTcpComm::DefaultDataPackets)
        : WRWorkTcpCommClientInterface(uuid, name, index, target), m_bufSize(buffers), m_pkgSize(packets), m_dataBuffer(0)
    {
        //add code here
    }

    //清理当前对象所占用的相关资源。
    ~WRWorkTcpCommClientDataSource(void)
    {
        if (m_dataBuffer)
        {
            m_dataBuffer->release();
        }
    }

    //创建当前接口的新接口。
    WRWorkTcpCommClientInterface* clone(WRWorkTcpCommClientObject* target)
    {
        return new WRWorkTcpCommClientDataSource(uuid(), name(), index(), target);
    }
    //创建当前接口的新接口。
    WRWorkTcpCommClientInterface* clone(WRWorkTcpCommClientAffair* target)
    {
        return new WRWorkTcpCommClientDataSource(uuid(), name(), index(), target);
    }

    //处理数据。
    void procData(const unsigned char* buf, int len)
    {
        WR16u action = *(const WR16u*)buf;
        buf += 6;
        len -= 6;
        switch(action)
        {
        case WRWorkTcpComm::DataStarted://数据启动
        {
            WR32s cnt = WRBytes::read<WR32s>(buf);
            buf += 4;
            len -= 4;
            if (cnt <= len)
            {
                TArgs val;
                if (m_argsParser.parse(buf, cnt, val))
                {
                    WRDataHandlers<TArgs, TData>::onStarted(val);
                }
                else
                {
                    //add code here to process on parsing failed!
                }
            }
            else
            {
                //add code here to process on message error!
            }
        }
            break;
        case WRWorkTcpComm::DataChanged://数据改变
        {
            WR32s cnt = WRBytes::read<WR32s>(buf);
            buf += 4;
            len -= 4;
            if (cnt <= len)
            {
                TArgs val;
                if (m_argsParser.parse(buf, cnt, val))
                {
                    WRDataHandlers<TArgs, TData>::onChanged(val);
                    if (m_dataBuffer)
                    {
                        m_dataBuffer->release();
                        m_dataBuffer = 0;
                    }
                }
                else
                {
                    //add code here to process on parsing failed!
                }
            }
            else
            {
                //add code here to process on message error!
            }
        }
            break;
        case WRWorkTcpComm::DataProcess:// 数据处理
        {
            WR32s datCount = WRBytes::read<WR32s>(buf);
            buf += 4;
            len -= 4;
            WR16u pkgTotal = WRBytes::read<WR16u>(buf);
            buf += 2;
            len -= 2;
            WR16u pkgIndex = WRBytes::read<WR16u>(buf);
            buf += 2;
            len -= 2;
            WR32s count = WRBytes::read<WR32s>(buf);
            buf += 4;
            len -= 4;
            if (count <= len)
            {
                if (pkgTotal == 1)//只有一包数据
                {
                    TData val;
                    if (m_dataParser.parse(buf, count, val))
                    {
                        WRDataHandlers<TArgs, TData>::doProcess(val);
                    }
                    else
                    {
                        //add code here to process on parsing failed!
                    }
                }
                else
                {
                    if (pkgIndex == 1)
                    {
                        if (!m_dataBuffer)
                        {
                            m_dataBuffer = new WRBuffer<unsigned char>();
                        }
                        m_dataBuffer->reset(datCount);
                        m_dataLength = 0;
                    }
                    if (m_dataBuffer)
                    {
                        memcpy(m_dataBuffer->array() + m_dataLength, buf, count);
                        m_dataLength += count;
                        if (pkgIndex == pkgTotal && m_dataLength == datCount)
                        {
                            TData val;
                            if (m_dataParser.parse(m_dataBuffer->array(), m_dataLength, val))
                            {
                                WRDataHandlers<TArgs, TData>::doProcess(val);
                            }
                            else
                            {
                                //add code here to process on parsing failed!
                            }
                        }
                    }
                }
            }
            else
            {
                //add code here to process on message error!
            }
        }
            break;
        case WRWorkTcpComm::DataStopped://数据启动
            WRDataHandlers<TArgs, TData>::onStopped();
            if (m_dataBuffer)
            {
                m_dataBuffer->release();
                m_dataBuffer = 0;
            }
            break;
        default:
            break;
        }
    }

    //获取数据源接口。
    WRDataSource* dataSource(void)
    {
        return this;
    }
};

//表示工作TCP通讯客户端数据源激活器。
template <class TArgs, class TData, class TArgsParser, class TDataParser, class TUuidValue, class TNameValue>
class WRWorkTcpCommClientDataSourceActivator : public WRWorkTcpCommClientInterfaceActivator
{
public:
    //初始化工作TCP通讯客户端数据源激活器。
    WRWorkTcpCommClientDataSourceActivator(void)
    {
        TUuidValue uuid;
        WRWorkTcpComm::enrollClientInterface(uuid(), this);
    }
    //释放当前对象所占用的相关资源。
    ~WRWorkTcpCommClientDataSourceActivator(void)
    {
        TUuidValue uuid;
        WRWorkTcpComm::cancelClientInterface(uuid());
    }

    //创建接口实例。
    WRWorkTcpCommClientInterface* create(int index, WRWorkTcpCommClientObject* target)
    {
        TUuidValue uuid;
        TNameValue name;
        return new WRWorkTcpCommClientDataSource<TArgs, TData, TArgsParser, TDataParser>(uuid(), name(), index, target);
    }
    //创建接口实例。
    WRWorkTcpCommClientInterface* create(int index, WRWorkTcpCommClientAffair* target)
    {
        TUuidValue uuid;
        TNameValue name;
        return new WRWorkTcpCommClientDataSource<TArgs, TData, TArgsParser, TDataParser>(uuid(), name(), index, target);
    }
};

#endif // WRWORKTCPCOMMCLIENTDATASOURCE
